﻿using Furion.ClayObject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Core
{
    /// <summary>
    /// 粘土对象 - 弱类型
    /// </summary>
    public class ClayDemo
    {
        #region 创建一个对象

        // 创建一个空的粘土对象
        dynamic clay = new Clay();

        // 从现有的对象创建
        dynamic clay2 = Clay.Object(new { });

        // 从json字符串创建，可用于第三方API对接，非常有用
        dynamic clay3 = Clay.Parse(@"{""foo"":""json"", ""bar"":100, ""nest"":{ ""foobar"":true } }");

        #endregion

        #region 读取/获取属性

        dynamic clay4 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            }
        });

        public void ReadOrGetAttribute()
        {
            var r1 = clay4.Foo; // "json" - string类型
            var r2 = clay4.Bar; // 100 - double类型
            var r3 = clay4.Nest.Foobar; // true - bool类型
            var r4 = clay4["Nest"]["Foobar"]; // 还可以和Javascript一样通过索引器获取
        }

        #endregion

        #region 新增属性

        dynamic clay5 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            }
        });

        public void AddAttribute()
        {
            // 新增
            clay5.Arr = new string[] { "NOR", "XOR" }; // 添加一个数组
            clay5.Obj1 = new City { }; // 新增一个实例对象
            clay5.Obj2 = new { Foo = "abc", Bar = 100 }; // 新增一个匿名类
        }

        #endregion

        #region 更新属性值

        dynamic clay6 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            }
        });

        public void UpdateAttribute()
        {
            // 更新
            clay6.Foo = "Furion";
            clay6["Nest"].Foobar = false;
            clay6.Nest["Foobar"] = true;
        }

        #endregion

        #region 删除属性

        dynamic clay7 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            },
            Arr = new string[] { "NOR", "XOR" }
        });

        public void DeleteAttribute()
        {
            // 删除操作
            clay7.Delete("Foo"); // 通过Delete方法删除
            clay7.Arr.Delete(0); // 支持数组Delete索引删除
            clay7("Bar");    // 支持直接通过对象作为方法删除
            clay7.Arr(1);    // 支持数组作为方法删除
        }

        #endregion

        #region 判断属性是否存在

        dynamic clay8 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            },
            Arr = new string[] { "NOR", "XOR" }
        });

        public void IsAttributeExist()
        {
            // 判断属性是否存在
            var a = clay8.IsDefined("Foo"); // true
            var b = clay8.IsDefined("Foooo"); // false
            var c = clay8.Foo(); // true
            var d = clay8.Foooo(); // false;
        }

        #endregion

        #region 遍历对象

        dynamic clay9 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            },
            Arr = new string[] { "NOR", "XOR" }
        });

        public void ErgodicObject()
        {
            // 遍历数组
            foreach (string item in clay9.Arr)
            {
                Console.WriteLine(item); // NOR, XOR
            }

            // 遍历整个对象属性及值，类似 JavaScript 的 for (var p in obj)
            foreach (KeyValuePair<string, dynamic> item in clay9)
            {
                Console.WriteLine(item.Key + ":" + item.Value); // Foo:json, Bar: 100, Nest: { "Foobar":true}, Arr:["NOR","XOR"]
            }
        }

        #endregion

        #region 转换成具体对象

        dynamic clay10 = new Clay();
        public void ConvertObject()
        {
            clay10.Arr = new string[] { "Furion", "Fur" };
            // 数组转换示例
            var a1 = clay10.Arr.Deserialize<string[]>(); // 通过Deserialize方法
            var a2 = (string[])clay10.Arr;    // 强制转换
            string[] a3 = clay10.Arr; // 声明方式

            // 对象转换示例
            clay10.City = new City { Id = 1, Name = "中山市" };
            var c1 = clay10.City.Deserialize<City>(); // 通过Deserialize方法
            var c2 = (City)clay10.City;    // 强制转换
            City c3 = clay10.City; // 声明方式
        }

        #endregion

        #region 固化粘土

        dynamic clay11 = new Clay();

        public void SolidifiedClay()
        {
            // 返回 object
            var obj = clay11.Solidify();

            // 返回 dynamic
            var obj1 = clay11.Solidify<dynamic>();

            // 返回其他任意类型
            var obj2 = clay11.Solidify<City>();
        }

        #endregion

        #region 输出JSON

        dynamic clay12 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            },
            Arr = new string[] { "NOR", "XOR" }
        });

        public void OutputJson()
        {
            // 输出 JSON
            var json = clay12.ToString(); // "{\"Foo\":\"json\",\"Bar\":100,\"Nest\":{\"Foobar\":true},\"Arr\":[\"NOR\",\"XOR\"]}"
        }

        #endregion

        #region 输出XML对象

        dynamic clay13 = Clay.Object(new
        {
            Foo = "json",
            Bar = 100,
            Nest = new
            {
                Foobar = true
            },
            Arr = new string[] { "NOR", "XOR" }
        });

        public void OutputXML()
        {
            // 输出 XElement
            var xml = clay13.XmlElement;
        }

        #endregion

        #region 关键字处理

        dynamic clay14= new Clay();

        public void KeywordProcessing()
        {
            clay14.@int = 1;
            clay14.@event = "事件";
        }

        #endregion

        #region 转换成字典类型

        dynamic clay15 = Clay.Object(new { name = "张三" });

        public void ConvertDictory()
        {
            clay15.name = "百小僧";
            Dictionary<string, object> parms = clay15.ToDictionary();
        }

        #endregion
    }
}
